﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YAPL.Language.Core.Lib;
using YAPL.Language.Core.Lib.GlobalFunctions;
using YAPL.Language.Core.Lib.GlobalFunctions.Math;
using YAPL.Language.Core.Lib.Strings;
using YAPL.Language.Core.Types;

namespace YAPL.Language.Core {
	/// <summary>
	/// Provides global class collection for all YAPL classes.
	/// </summary>
	public static class GCL {
		private static readonly Dictionary<string, YAPLClass> _classes = new Dictionary<string, YAPLClass>();
		public static void Add(YAPLClass yaplClass) {
			_classes[yaplClass.Name] = yaplClass;
		}
		static GCL() {
			//define classes
			DefineClass(ClassNames.GlobalScope);
			DefineClass(ClassNames.YAPLString);
			DefineClass(ClassNames.YAPLObject);

			//create functions
			new Print();
			new GetLine();
			new ParseFloat();
			new ParseInt();
			new ParseBool();
			new TypeName();
			new Pow();
			new Reverse();
		}
		public static YAPLClass Get(string className) {
			return _classes[className];
		}

		public static void DefineClass(string className) {
			if (!_classes.ContainsKey(className)) {
				var metaclassName = YAPLClass.GetMetaclassNameForClass(className);
				Add(YAPLClass.CreateMetaclass(className));
				Add(YAPLClass.CreateClass(className));
				new NoMethod(className);
				new ClassConstructor(metaclassName);
				new ClassMetaclassName(metaclassName);
				new NoMethod(metaclassName);
			}
		}

		public static void CloneClass(string source, string dest) {
			if (!_classes.ContainsKey(dest)) {
				Add(YAPLClass.CreateClass(dest, YAPLClass.GetMetaclassNameForClass(source)));
				var sourceClass = Get(source);
				var destClass = Get(dest);

				foreach (var func in sourceClass.Methods) {
					destClass.Methods[func.Name] = func;
				}
			}
		}
	}
}
